package think.in.java.concurrency.PractiseOneMoreTime;

import org.hsqldb.jdbc.jdbcCallableStatement;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Create a non-task class with a method that calls sleep( ) for a long interval.
 * Create a task that calls the method in the non-task class.
 * In main( ), start the task, then call interrupt( ) to terminate it. Make sure that the task shuts down safely.
 * Also add a method for stopping with interruption
 */
public class Exercise18InterruptTask {
    public static void main(String[] args) throws InterruptedException {
        Exercise18InterruptTask exercise18InterruptTask = new Exercise18InterruptTask();
        exercise18InterruptTask.callInterrupted();
        exercise18InterruptTask.callShutdown();

    }

    public void callInterrupted() throws InterruptedException {
        Thread thread = new Thread(new Caller());
        thread.start();
        Thread.sleep(3000);
        thread.interrupt();

    }

    public void callShutdown() throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Thread thread = new Thread(  new Caller());
        executorService.execute(thread);
        Thread.sleep(3000);

        executorService.shutdownNow();// must call this method, other method will not send the interrupt to its threads

    }
}

class Caller implements Runnable {

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {

                new IntervalTime().sleep();
                System.out.println("Task is Running");
                Thread.yield();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();// note, we should place the catch outside of the while
            // if this thread is blocked in an invocation of the wait(),
            // wait(long), or wait(long, int) methods of the Object class,
            // or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int),
            // methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
        }
        System.out.println("Task is interrupted");
    }
}

class IntervalTime {
    public void sleep() throws InterruptedException {
        Thread.sleep(100);
    }
}
